HAL FLASH IO function migration

This section provides information about the HAL FLASH function migration.

Note

  • In HAL1, the FLASH driver manages Flash memory operations.

  • In HAL2, depending on the device family, memory operations are managed either by the FLASH driver or by the NVM driver.

  • In this migration guide, when a HAL2 function exists for both FLASH and NVM, the migration is illustrated using the HAL2 FLASH function. The same migration rule applies to the HAL2 NVM function.

  • Example: in HAL1, HAL_FLASHEx_GetOperation() function becomes:

    • HAL_FLASH_GetInterruptedByResetOperationInfo() in HAL2 FLASH driver.

    • HAL_NVM_GetInterruptedByResetOperationInfo() in HAL2 NVM driver.

  • For NVM-based families, the NVM driver provides programming services similar to those of FLASH with minor differences:

    • There is no erase step for NVM memories.

      • Erase-by-address, page erase, bank erase, and FLASH mass erase remain FLASH-specific.

      • For NVM-based families, the only erase service that may be exposed is OBK erase, when that feature exists.

Handles FLASH bus fault interrupts.

HAL1

HAL2

Function prototype

HAL_FLASHEx_BusFault_IRQHandler()
/* Double-error / NMI path */
HAL_FLASH_NMI_IRQHandler(&hflash);

Erases FLASH memory.

Important

In HAL1, FLASH erase operations were performed using a single API:

HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);

where the erase configuration was specified through the FLASH_EraseInitTypeDef structure containing parameters such as:

  • TypeErase: to select mass erase or sector erase.

  • Banks: to select the bank(s) to erase.

  • Sector: the initial sector to erase.

  • NbSectors: the number of sectors to erase.

and the parameter SectorError is passed by pointer to get the first sector that failed to erase in case of error.

In HAL2, the erase APIs have been redesigned to provide more granular and flexible control, with dedicated functions for different erase operations:

  • Erase by address:

    HAL_FLASH_{area}_EraseByAddr();
    
  • Erase by page:

    HAL_FLASH_{area}_ErasePage();
    
  • Erase by bank:

    HAL_FLASH_EraseBank();
    
  • Mass erase:

    HAL_FLASH_MassErase();
    

HAL1

HAL2

Function prototype

HAL_FLASHEx_Erase(const FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError);
/* Note: In HAL2, the single HAL_FLASHEx_Erase() call is split into
   several unitary HAL2 APIs depending on the erase granularity. */
 hal_status_t status;

 status = HAL_FLASH_EraseByAddr(hal_flash_handle_t *hflash, uint32_t flash_addr, uint32_t size_byte, uint32_t timeout_msec);
 status = HAL_FLASH_ErasePage(hal_flash_handle_t *hflash, hal_flash_bank_t bank, uint32_t page, uint32_t page_nbr, uint32_t timeout_msec);
 status = HAL_FLASH_EraseBank(hal_flash_handle_t *hflash, hal_flash_bank_t bank, uint32_t timeout_msec);
 status = HAL_FLASH_MassErase(hal_flash_handle_t *hflash, uint32_t timeout_msec);
 /* Note: The status variable should be checked to ensure the erase operation was successful.
    Its value could be HAL_OK, HAL_ERROR or HAL_TIMEOUT.
    HAL_FLASH_GetLastError() can be used to retrieve the error code (e.g: HAL_FLASH_ERROR_WRP,..). */

Example usage

FLASH_EraseInitTypeDef eraseInit;
uint32_t pageError;

eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS; /* or MASSERASE */
eraseInit.Banks = /* target bank(s) */;
eraseInit.Sector = /* start sector */;
eraseInit.NbSectors = /* number of sectors */;

HAL_FLASHEx_Erase(&eraseInit, &pageError);
hal_flash_handle_t hflash;

/* Page(s) erase (map from FLASH_TYPEERASE_SECTORS) */
 HAL_FLASH_ErasePage(&hflash, HAL_FLASH_BANK_1, /*page*/, /*page_nbr*/, TIMEOUT);

/* Address erase */
 HAL_FLASH_EraseByAddr(&hflash, /*start_address*/, /*length_bytes*/, TIMEOUT);

/* Bank erase */
 HAL_FLASH_EraseBank(&hflash, HAL_FLASH_BANK_1, TIMEOUT);

/* Mass erase */
 HAL_FLASH_MassErase(&hflash, TIMEOUT);

Erases FLASH memory using interrupt mode.

HAL1

HAL2

Function prototype

HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit);
/* HAL2 interrupt-mode erase prototypes */
 HAL_FLASH_EraseByAddr_IT(hal_flash_handle_t *hflash, uint32_t flash_addr, uint32_t size_byte);
 HAL_FLASH_ErasePage_IT(hal_flash_handle_t *hflash, hal_flash_bank_t bank, uint32_t page, uint32_t page_nbr);
 HAL_FLASH_EraseBank_IT(hal_flash_handle_t *hflash, hal_flash_bank_t bank);
 HAL_FLASH_MassErase_IT(hal_flash_handle_t *hflash);

Example usage

FLASH_EraseInitTypeDef eraseInit;
uint32_t pageError;

eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS; /* or MASSERASE */
eraseInit.Banks = /* target bank(s) */;
eraseInit.Sector = /* start sector */;
eraseInit.NbSectors = /* number of sectors */;

HAL_FLASHEx_Erase_IT(&eraseInit);
extern hal_flash_handle_t hflash;

/* Page(s) erase (IT mode) */
 HAL_FLASH_ErasePage_IT(&hflash, HAL_FLASH_BANK_1, /*page*/, /*page_nbr*/);

/* Address erase (IT mode) */
 HAL_FLASH_EraseByAddr_IT(&hflash, /*start_address*/, /*length_bytes*/);

Gets current FLASH operation.

HAL1

HAL2

Function prototype

void HAL_FLASHEx_GetOperation(FLASH_OperationTypeDef *pFlashOperation);
/* Retrieve info about an operation interrupted by a reset
  and returns a struct with operation code and address */
void HAL_FLASH_GetInterruptedByResetOperationInfo(const hal_flash_handle_t *hflash,
                                 hal_flash_interrupted_by_reset_operation_info_t *p_info);

Example usage

/* HAL1: get the current FLASH operation */
FLASH_OperationTypeDef op;
HAL_FLASHEx_GetOperation(&op);
/* op now contains the operation type/address */
hal_flash_interrupted_by_reset_operation_info_t info;
extern hal_flash_handle_t hflash;
HAL_FLASH_GetInterruptedByResetOperationInfo(&hflash, &info);
/* info.operation contains a hal_flash_interrupted_operation_t enum
  (e.g. HAL_FLASH_INTERRUPTED_PAGE_ERASE) and info.addr the address */

Callback called at the end of a FLASH operation.

HAL1

HAL2

Function prototype

void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue);
/* HAL2: callbacks are provided per-operation as weak functions like HAL1.*/

   void HAL_FLASH_ProgramCpltCallback(hal_flash_handle_t *hflash, uint32_t flash_addr, uint32_t size_byte);
   void HAL_FLASH_EraseByAddrCpltCallback(hal_flash_handle_t *hflash, uint32_t flash_addr, uint32_t size_byte);
   void HAL_FLASH_ErasePageCpltCallback(hal_flash_handle_t *hflash, hal_flash_bank_t bank, uint32_t page, uint32_t page_nbr);
   void HAL_FLASH_EraseBankCpltCallback(hal_flash_handle_t *hflash, hal_flash_bank_t bank);
   void HAL_FLASH_MassEraseCpltCallback(hal_flash_handle_t *hflash);

   /* In addition in HAL2 they can be registered when USE_HAL_FLASH_REGISTER_CALLBACKS
   thanks to the following functions: */
    HAL_FLASH_RegisterProgramCpltCallback(hal_flash_handle_t *hflash, hal_flash_program_cplt_cb_t callback);
    HAL_FLASH_RegisterEraseByAddrCpltCallback(hal_flash_handle_t *hflash, hal_flash_erase_by_addr_cplt_cb_t callback);
    HAL_FLASH_RegisterErasePageCpltCallback(hal_flash_handle_t *hflash, hal_flash_erase_page_cplt_cb_t callback);
    HAL_FLASH_RegisterEraseBankCpltCallback(hal_flash_handle_t *hflash, hal_flash_erase_bank_cplt_cb_t callback);
    HAL_FLASH_RegisterMassEraseCpltCallback(hal_flash_handle_t *hflash, hal_flash_mass_erase_cplt_cb_t callback);
    HAL_FLASH_RegisterErrorCallback(hal_flash_handle_t *hflash, hal_flash_error_cb_t callback);

Example usage

/* HAL1 example implementation (running a program operation): called when a FLASH operation completes */
void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
{
    if (ReturnValue == HAL_OK) {
        /* operation successful - user code here */
    } else {
        /* error handling */
    }
}
/* Example: overwrite a program-complete callback */
extern hal_flash_handle_t hflash;
void my_program_cplt(hal_flash_handle_t *hflash, uint32_t addr, uint32_t size)
{
    /* application-specific handling */
}

/* Or register the user callback function */
HAL_FLASH_RegisterProgramCpltCallback(&hflash, my_program_cplt);

Retrieves the current FLASH error code.

HAL1

HAL2

Function prototype

uint32_t HAL_FLASH_GetError(void)
/* HAL2 equivalents: per-handle last-error getters.
  available only when USE_HAL_FLASH_GET_LAST_ERRORS is enabled */
uint32_t HAL_FLASH_GetLastErrorCodes(const hal_flash_handle_t *hflash);

Example usage

/* HAL1 usage example */
uint32_t err = HAL_FLASH_GetError();
/* HAL2 example usage */
extern hal_flash_handle_t hflash;

uint32_t last_errors = HAL_FLASH_GetLastErrorCodes(&hflash);

Handles FLASH interrupts.

HAL1

HAL2

Function prototype

/* HAL1 prototype */
void HAL_FLASH_IRQHandler(void);
/* Either call HAL_FLASH_IRQHandler and it handle all possible interrupt
 including program, erase and ECC interrupts  */
void HAL_FLASH_IRQHandler(hal_flash_handle_t *hflash);

/*or call only the required and specialized IRQHandler from the following list:*/
 void HAL_FLASH_Program_IRQHandler(hal_flash_handle_t *hflash);
 void HAL_FLASH_EraseByAddr_IRQHandler(hal_flash_handle_t *hflash);
 void HAL_FLASH_ErasePage_IRQHandler(hal_flash_handle_t *hflash);
 void HAL_FLASH_EraseBank_IRQHandler(hal_flash_handle_t *hflash);
 void HAL_FLASH_MassErase_IRQHandler(hal_flash_handle_t *hflash);
 void HAL_FLASH_ECC_IRQHandler(hal_flash_handle_t *hflash);

/* Example if the user application will perform only programming user can call only HAL_FLASH_Program_IRQHandler()*/

Programs data into FLASH memory

HAL1

HAL2

Function prototype

HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress);
/* HAL2 polling-mode programs prototypes */
  HAL_FLASH_ProgramByAddr(hal_flash_handle_t *hflash, uint32_t flash_addr, const uint32_t *p_data, uint32_t size_byte, uint32_t timeout_msec);

  HAL_FLASH_OTP_ProgramByAddr(hal_flash_handle_t *hflash, uint32_t otp_addr, const uint32_t *p_data, uint32_t size_byte, uint32_t timeout_msec);

  HAL_FLASH_EDATA_ProgramByAddr(hal_flash_handle_t *hflash, uint32_t data_addr, const uint32_t *p_data, uint32_t size_byte, uint32_t timeout_msec);

  HAL_FLASH_OBK_ProgramByAddr(hal_flash_handle_t *hflash, hal_flash_obk_page_t obk_page, uint32_t obk_addr, const uint32_t *p_data, uint32_t size_byte, uint32_t timeout_msec);

Note

  • In HAL2, HAL_FLASH_SetProgrammingMode(hal_flash_handle_t *hflash, hal_flash_program_mode_t programming_mode) allows the user to choose the desired programming mode (WORD, QUADWORD, …). This function is not mandatory as the default programming mode will be set up during HAL_FLASH_Init().

  • In addition, the HAL FLASH driver offers a set of programming API variants (calling HAL_FLASH_ProgramByAddrAdapt(), …) that automatically adapt the programming mode according to the user buffer and size_byte to perform the programming operation in the most efficient way (in terms of access of the user buffer and flash). These Adapt variant functions do not require calling HAL_FLASH_SetProgrammingMode() as it will be adapted automatically.

Example usage

uint32_t data_to_program[/* size */] = { /* data values */ };
uint32_t flash_address = /* target FLASH address */;
uint32_t type_program = /* program type, e.g. FLASH_TYPEPROGRAM_WORD */;

HAL_FLASH_Program(type_program, flash_address, (uint32_t)data_to_program);
extern hal_flash_handle_t hflash;
uint32_t data_to_program[/* size */] = { /* data values */ };
uint32_t flash_address = /* target FLASH address */;
uint32_t size_in_bytes = /* size of data_to_program in bytes */;

/* Program FLASH by address */
HAL_FLASH_ProgramByAddr(&hflash, flash_address, data_to_program, size_in_bytes, TIMEOUT);

/* Program OTP area by address */
 HAL_FLASH_OTP_ProgramByAddr(&hflash, /* otp_address */, data_to_program, size_in_bytes, TIMEOUT);

/* Program EDATA area by address */
 HAL_FLASH_EDATA_ProgramByAddr(&hflash, /* edata_address */, data_to_program, size_in_bytes, TIMEOUT);

/* Program OBK area by address */
 HAL_FLASH_OBK_ProgramByAddr(&hflash, HAL_FLASH_OBK_PAGE_0, /* obk_address */, data_to_program, size_in_bytes, TIMEOUT);

Programs data into FLASH memory using interrupt mode.

HAL1

HAL2

Function prototype

HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
/* HAL1 TypeProgram removed: select region API + provide p_data + size_byte */
 HAL_FLASH_ProgramByAddr_IT(hal_flash_handle_t *hflash, uint32_t flash_addr, const uint32_t *p_data, uint32_t size_byte);
 HAL_FLASH_OTP_ProgramByAddr_IT(hal_flash_handle_t *hflash, uint32_t otp_addr, const uint32_t *p_data, uint32_t size_byte);
 HAL_FLASH_EDATA_ProgramByAddr_IT(hal_flash_handle_t *hflash, uint32_t data_addr, const uint32_t *p_data, uint32_t size_byte);
 HAL_FLASH_OBK_ProgramByAddr_IT(hal_flash_handle_t *hflash, hal_flash_obk_page_t obk_page, uint32_t obk_addr, const uint32_t *p_data, uint32_t size_byte);

Example usage

uint64_t data_to_program = /* 64-bit data value */;
uint32_t flash_address = /* target FLASH address */;
uint32_t type_program = /* program type, e.g. FLASH_TYPEPROGRAM_DOUBLEWORD */;

HAL_FLASH_Program_IT(type_program, flash_address, data_to_program);
extern hal_flash_handle_t hflash;
uint32_t data_to_program[/* size */] = { /* data values */ };
uint32_t flash_address = /* target FLASH address */;
uint32_t size_in_bytes = /* size of data_to_program in bytes */;

/* Program FLASH by address (interrupt mode) */
HAL_FLASH_ProgramByAddr_IT(&hflash, flash_address, data_to_program, size_in_bytes);

/* Program OTP area by address (interrupt mode) */
 HAL_FLASH_OTP_ProgramByAddr_IT(&hflash, /* otp_address */, data_to_program, size_in_bytes);

/* Program EDATA area by address (interrupt mode) */
 HAL_FLASH_EDATA_ProgramByAddr_IT(&hflash, /* edata_address */, data_to_program, size_in_bytes);

/* Program OBK area by address (interrupt mode) */
 HAL_FLASH_OBK_ProgramByAddr_IT(&hflash, HAL_FLASH_OBK_PAGE_0, /* obk_address */, data_to_program, size_in_bytes);